﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using TournamentDatabase.Objects;
using TournamentDatabase.DialogBoxes.Edit;
using TournamentDatabase.DialogBoxes.Select;
using TournamentDatabase.Database;
using TournamentDatabase.Singletons;

namespace TournamentDatabase.Views
{
	/// <summary>
	/// Interaction logic for CompetitionView.xaml
	/// </summary>
	public partial class CompetitionView : Window
	{
		Competition m_competition;
		List<CompetesIn> m_competitors;
		List<JudgesIn> m_judges;
		string m_competitorSearchText;
		string m_judgeSearchText;
		Competitor m_competitorSelected;
		Judge m_judgeSelected;

		public Judge JudgeSelected
		{
			get { return m_judgeSelected; }
			set { m_judgeSelected = value; }
		}

		public Competitor CompetitorSelected
		{
			get { return m_competitorSelected; }
			set { m_competitorSelected = value; }
		}

		public string JudgeSearchText
		{
			get { return m_judgeSearchText; }
			set { m_judgeSearchText = value; }
		}

		public string CompetitorSearchText
		{
			get { return m_competitorSearchText; }
			set { m_competitorSearchText = value; }
		}

		public List<JudgesIn> Judges
		{
			get { return m_judges; }
			set { m_judges = value; }
		}

		public List<CompetesIn> Competitors
		{
			get { return m_competitors; }
			set { m_competitors = value; }
		}

		public Competition Competition
		{
			get { return m_competition; }
			set { m_competition = value; }
		}

		public CompetitionView(Competition comp)
		{
			InitializeComponent();

			m_competition = comp;

			this.DataContext = this;
		}

		#region Competitors

		private void addCompetitorButton_Click(object sender, RoutedEventArgs e)
		{
			CompetitorSelectDialogBox csdb = new CompetitorSelectDialogBox();

			csdb.ShowDialog();

			if (csdb.DialogResult.HasValue && csdb.DialogResult.Value)
			{
				CompetesInEditDialogBox cedb = new CompetesInEditDialogBox(csdb.SelectedCompetitor, m_competition);

				if (cedb.DialogResult.HasValue && cedb.DialogResult.Value)
				{
					CompetitorSearch();
				}
			}
		}

		private void deleteCompetitorButton_Click(object sender, RoutedEventArgs e)
		{
			if (m_competitorSelected == null)
				return;

			string messageBoxText = "Do you really want to remove this competitor?";
			string caption = "This will remove the placing information for this competitor.";
			MessageBoxButton btnMessageBox = MessageBoxButton.YesNo;
			MessageBoxImage icnMessageBox = MessageBoxImage.Warning;
			MessageBoxResult rsltMessageBox = MessageBox.Show(messageBoxText, caption, btnMessageBox, icnMessageBox);

			// Process message box results
			if (rsltMessageBox == MessageBoxResult.Yes)
			{
				DatabaseSingleton.GetDatabaseAccessor().DeleteCompetitor(m_competitorSelected);

				CompetitorSearch();
			}
		}

		private void OnCompetitorSearch(string searchText)
		{
			m_competitorSearchText = searchText;
			CompetitorSearch();
		}

		private void CompetitorSearch()
		{
			string where = string.Format("tid = {0} AND type = '{1}' AND minBirthDate = TO_DATE('{2}','DD/MM/YYYY') AND maxBirthDate = TO_DATE('{3}','DD/MM/YYYY') AND gender = '{4}'",
				m_competition.TournamentID,
				m_competition.Type,
				// TODO: Format these dates correctly...
				m_competition.MinBirthDate,
				m_competition.MaxBirthDate,
				m_competition.Gender);

			if (m_competitorSearchText == null || m_competitorSearchText.Length == 0)
			{
				m_competitors = DatabaseSingleton.GetDatabaseAccessor().QueryCompetesIn(where, OrderBy.None, "");
			}
			else
			{
				where += " AND name LIKE '%" + m_competitorSearchText + "%'";
				m_competitors = DatabaseSingleton.GetDatabaseAccessor().QueryCompetesIn(where, OrderBy.None, "");
			}
		}

		#endregion

		#region Judges

		private void addJudgeButton_Click(object sender, RoutedEventArgs e)
		{
			JudgeSelectDialogBox jsdb = new JudgeSelectDialogBox();

			jsdb.ShowDialog();

			if (jsdb.DialogResult.HasValue && jsdb.DialogResult.Value)
			{
				JudgesInEditDialogBox jedb = new JudgesInEditDialogBox(jsdb.SelectedJudge, m_competition);

				if (jedb.DialogResult.HasValue && jedb.DialogResult.Value)
				{
					JudgeSearch();
				}
			}
		}

		private void deleteJudgeButton_Click(object sender, RoutedEventArgs e)
		{
			if (m_judgeSelected == null)
				return;

			string messageBoxText = "Do you really want to remove this judge?";
			string caption = "This will delete the judging information for this judge.";
			MessageBoxButton btnMessageBox = MessageBoxButton.YesNo;
			MessageBoxImage icnMessageBox = MessageBoxImage.Warning;
			MessageBoxResult rsltMessageBox = MessageBox.Show(messageBoxText, caption, btnMessageBox, icnMessageBox);

			// Process message box results
			if (rsltMessageBox == MessageBoxResult.Yes)
			{
				DatabaseSingleton.GetDatabaseAccessor().DeleteJudge(m_judgeSelected);

				JudgeSearch();
			}
		}

		private void OnSearchJudge(string searchText)
		{
			m_judgeSearchText = searchText;
			JudgeSearch();
		}

		private void JudgeSearch()
		{
			string where = string.Format("tid = {0} AND type = '{1}' AND minBirthDate = TO_DATE('{2}','DD/MM/YYYY') AND maxBirthDate = TO_DATE('{3}','DD/MM/YYYY') AND gender = '{4}'",
				m_competition.TournamentID,
				m_competition.Type,
				// TODO: Format these dates correctly...
				m_competition.MinBirthDate,
				m_competition.MaxBirthDate,
				m_competition.Gender);

			if (m_judgeSearchText == null || m_judgeSearchText.Length == 0)
			{
				m_judges = DatabaseSingleton.GetDatabaseAccessor().QueryJudgesIn(where, OrderBy.None, "");
			}
			else
			{
				where += " AND name LIKE '%" + m_competitorSearchText + "%'";
				m_judges = DatabaseSingleton.GetDatabaseAccessor().QueryJudgesIn(where, OrderBy.None, "");
			}
		}

		#endregion

		private void okButton_Click(object sender, RoutedEventArgs e)
		{
			if (!IsValid(this))
				return;

			try
			{
				DatabaseSingleton.GetDatabaseAccessor().UpdateCompetition(m_competition);
			}
			catch
			{
				MessageBox.Show("Error saving to the database!");
				return;
			}

			this.DialogResult = true;
		}

		bool IsValid(DependencyObject node)
		{
			// Check if dependency object was passed
			if (node != null)
			{
				// Check if dependency object is valid.
				// NOTE: Validation.GetHasError works for controls that have validation rules attached 
				bool isValid = !Validation.GetHasError(node);
				if (!isValid)
				{
					// If the dependency object is invalid, and it can receive the focus,
					// set the focus
					if (node is IInputElement) Keyboard.Focus((IInputElement)node);
					return false;
				}
			}

			// If this dependency object is valid, check all child dependency objects
			foreach (object subnode in LogicalTreeHelper.GetChildren(node))
			{
				if (subnode is DependencyObject)
				{
					// If a child dependency object is invalid, return false immediately,
					// otherwise keep checking
					if (IsValid((DependencyObject)subnode) == false) return false;
				}
			}

			// All dependency objects are valid
			return true;
		}
	}
}
